package com.yonyou.cyxdms.basedata.client.service.basedata;

import com.fasterxml.jackson.core.type.TypeReference;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.yonyou.cyx.framework.bean.dto.base.ClientInfoDTO;
import com.yonyou.cyx.framework.bean.dto.framework.RestResultResponse;
import com.yonyou.cyx.framework.compent.redis.RedisClient;
import com.yonyou.cyx.framework.util.bean.ApplicationContextHelper;
import com.yonyou.cyx.function.utils.common.CommonUtils;
import com.yonyou.cyx.function.utils.jsonserializer.JSONUtil;
import com.yonyou.cyxdms.basedata.client.constants.BaseDataCommonConstants;
import com.yonyou.cyxdms.basedata.client.domains.vo.ModelCacheVO;
import com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO;
import com.yonyou.cyxdms.basedata.client.dto.RegionConditionDTO;
import com.yonyou.cyxdms.basedata.client.feign.BaseDataCommonClient;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 省市区县
 *
 * @author dengqiang
 * @since 2019/8/21
 */
@Service
public class BaseCommonRegionServiceImpl implements BaseCommonRegionService {

    private final Logger logger = LoggerFactory.getLogger(BaseCommonRegionServiceImpl.class);

    @Autowired
    private BaseDataCommonClient baseDataCommonClient;

    @Autowired
    private RedisClient redisClient;

    /**
     * 查询所有省市区数据
     *
     * @param
     * @return java.util.List<com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO>
     * @author dengqiang
     * @since 2019/8/21
     */
    @Override
    public List<RegionVO> listAllData() {
        ClientInfoDTO loginInfoDto = ApplicationContextHelper.getBeanByType(ClientInfoDTO.class);
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.REGION_CACHE_REGION, loginInfoDto.getAppId());
        Object regionDto = redisClient.get(messageFormat);
        if (null == regionDto) {
            // 查询所有数据
            loadValueIfNotExists(messageFormat);
            Object redisregionDto = redisClient.get(messageFormat);
            if (null == redisregionDto) {
                return null;
            }
            return JSONUtil.jsonToList(JSONUtil.objectToJson(redisregionDto), RegionVO.class);
        } else {
            return JSONUtil.jsonToList(JSONUtil.objectToJson(regionDto), RegionVO.class);
        }
    }

    /**
     * 查询数据
     *
     * @param
     * @return void
     * @author dengqiang
     * @since 2019/8/21
     */
    private void loadValueIfNotExists(String message) {
        List<RegionVO> regionResponse = baseDataCommonClient.listAllData().getData();
        logger.info("feign查询region信息:{}", regionResponse);

        if (!CommonUtils.isNullOrEmpty(regionResponse)) {
            initOneValue(regionResponse, message);
        }
    }

    /**
     * 将数据放置redis
     *
     * @param regionList
     * @return void
     * @author dengqiang
     * @since 2019/8/21
     */
    private void initOneValue(List<RegionVO> regionList, String message) {
        redisClient.set(message, JSONUtil.objectToJson(regionList), BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
    }

    /**
     * 根据regionId查询省市区数据
     *
     * @param
     * @return java.util.List<com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO>
     * @author dengqiang
     * @since 2019/9/16
     */
    @Override
    public RegionVO dataByRegionId(Long regionId) {
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.REGION_CACHE_REGION_ID, regionId);
        Object regionDto = redisClient.get(messageFormat);
        if (null == regionDto) {
            // 查询所有数据
            RestResultResponse<RegionVO> region = baseDataCommonClient.getRegionById(regionId);
            RegionVO regionVO = null;
            if (null != region && region.getResultCode() == 200 && region.getData() != null) {
                regionVO = region.getData();
            }
            if (null == regionVO) {
                return null;
            } else {
                redisClient.set(messageFormat, JSONUtil.objectToJson(regionVO), BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
                return regionVO;
            }
        } else {
            return JSONUtil.jsonToObj(JSONUtil.objectToJson(regionDto), RegionVO.class);
        }
    }

    /**
     * 未登录根据regionId查询省市区数据
     *
     * @param regionId
     * @param appId
     * @return com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO
     * @author renwd
     * @since 2019/12/3
     */
    @Override
    public RegionVO getDataByRegionId(Long regionId, String appId) {
        List<RegionVO> regionVOS = listAllDataWithoutLogin(appId);
        if (CollectionUtils.isNotEmpty(regionVOS)) {
            for (RegionVO regionVO : regionVOS) {
                if (ObjectUtil.equal(regionId, regionVO.getRegionId())) {
                    return regionVO;
                }
            }
        }
        return null;
    }

    /**
     * 根据regionCode查询省市区数据
     *
     * @param regionCode
     * @return java.util.List<com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO>
     * @author dengqiang
     * @since 2019/9/16
     */
    @Override
    public RegionVO dataByRegionCode(String regionCode) {
        List<RegionVO> regionVOS = listAllData();
        if (CollectionUtils.isNotEmpty(regionVOS)) {
            for (RegionVO regionVO : regionVOS) {
                if (ObjectUtil.equal(regionCode, regionVO.getRegionCode())) {
                    return regionVO;
                }
            }
        }
        return null;
    }

    /**
     * 未登录通过code获取省市区
     *
     * @param regionCode code
     * @param appId      appId
     * @return com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO
     * @author renwd
     * @since 2019/12/3
     */
    @Override
    public RegionVO getDataByRegionCode(String regionCode, String appId) {
        List<RegionVO> regionVOS = listAllDataWithoutLogin(appId);
        if (CollectionUtils.isNotEmpty(regionVOS)) {
            for (RegionVO regionVO : regionVOS) {
                if (ObjectUtil.equal(regionCode, regionVO.getRegionCode())) {
                    return regionVO;
                }
            }
        }
        return null;
    }

    /**
     * 根据regionName查询省市区数据
     *
     * @param regionName
     * @return java.util.List<com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO>
     * @author dengqiang
     * @since 2019/9/16
     */
    @Override
    public RegionVO dataByRegionName(String regionName) {
        List<RegionVO> regionVOS = listAllData();
        if (CollectionUtils.isNotEmpty(regionVOS)) {
            for (RegionVO regionVO : regionVOS) {
                if (ObjectUtil.equal(regionName, regionVO.getRegionName())) {
                    return regionVO;
                }
            }
        }
        return null;
    }

    /**
     * 通用根据城市名称查询省市区ID列表
     *
     * @param
     * @return java.util.List<java.lang.Long>
     * @author dengqiang
     * @since 2019/10/31
     */
    @Override
    public List<Long> getRegionIdList(RegionConditionDTO regionConditionDTO) {
        return baseDataCommonClient.getRegionIdList(regionConditionDTO).getData();
    }

    /**
     * 通用根据城市名称查询省市区ID列表
     *
     * @param
     * @return map<regionId, regionVO>
     * @author tanjie
     * @since 2019/10/31
     */
    @Override
    public Map<Long, RegionVO> getAllRegion(String appId) {
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.REGION_CACHE_REGION_APPID, appId);
        Object regionDto = redisClient.get(messageFormat);
        if (null == regionDto) {
            // 查询所有数据
            List<RegionVO> data = baseDataCommonClient.getAllRegion(appId).getData();
            logger.info("feign查询series信息:{}", data);
            if (!CommonUtils.isNullOrEmpty(data)) {
                Map<Long, RegionVO> regionMap = new HashMap<>();
                data.stream().forEach(e -> regionMap.put(e.getRegionId(), e));
                redisClient.set(messageFormat, JSONUtil.objectToJson(regionMap),
                        BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
            }
            Object redisAllRegion = redisClient.get(messageFormat);
            if (null == redisAllRegion) {
                return null;
            }
            return JSONUtil.jsonToObj(JSONUtil.objectToJson(redisAllRegion), new TypeReference<Map<Long, RegionVO>>() {
            });
        } else {
            return JSONUtil.jsonToObj(JSONUtil.objectToJson(regionDto), new TypeReference<Map<Long, RegionVO>>() {
            });
        }
    }

    /**
     * 未登录获取省市区
     *
     * @param appId appId
     * @return java.util.List<com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO>
     * @author renwd
     * @since 2019/12/3
     */
    @Override
    public List<RegionVO> listAllDataWithoutLogin(String appId) {
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.REGION_CACHE_REGION, appId);
        Object regionDto = redisClient.get(messageFormat);
        if (null == regionDto) {
            // 查询所有数据
            List<RegionVO> regionResponse = baseDataCommonClient.getAllRegion(appId).getData();
            logger.info("listAllDataWithoutLogin:{}", regionResponse);
            if (!CommonUtils.isNullOrEmpty(regionResponse)) {
                initOneValue(regionResponse, messageFormat);
            }
            Object redisRegionDto = redisClient.get(messageFormat);
            if (null == redisRegionDto) {
                return null;
            }
            return JSONUtil.jsonToList(JSONUtil.objectToJson(redisRegionDto), RegionVO.class);
        } else {
            return JSONUtil.jsonToList(JSONUtil.objectToJson(regionDto), RegionVO.class);
        }
    }

    /**
     * 查询所有省
     *
     * @param
     * @return java.util.List<com.yonyou.cyxdms.basedata.service.vo.region.RegionVO>
     * @author wy
     * @since 2020/2/24
     */
    @Override
    public List<RegionVO> listAllProvice() {
        List<RegionVO> regionResponse = baseDataCommonClient.listAllProvice().getData();
        return regionResponse;
    }

}
